package com.dy.yunying.biz.service.currency.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dy.yunying.api.constant.DistributedLock;
import com.dy.yunying.api.entity.CurrencyRechargeConfigDO;
import com.dy.yunying.api.vo.CurrencyRechargeConfigVO;
import com.dy.yunying.biz.dao.manage.CurrencyRechargeConfigMapper;
import com.dy.yunying.biz.service.currency.CurrencyRechargeConfigService;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author MyPC
 * @description 针对表【currency_recharge_config(游豆充值配置表)】的数据库操作Service实现
 * @createDate 2022-03-28 11:22:30
 */
@Service
@RequiredArgsConstructor
public class CurrencyRechargeConfigServiceImpl extends ServiceImpl<CurrencyRechargeConfigMapper, CurrencyRechargeConfigDO> implements CurrencyRechargeConfigService {

	private final CurrencyRechargeConfigMapper currencyRechargeConfigMapper;

	private final RedissonClient redissonClient;

	/**
	 * 分页列表
	 *
	 * @param config
	 * @return
	 */
	@Transactional(readOnly = true, rollbackFor = Exception.class)
	@Override
	public Page<CurrencyRechargeConfigDO> list(CurrencyRechargeConfigVO config) {
		final String currencyName = StringUtils.trim(config.getCurrencyName());
		final LambdaQueryWrapper<CurrencyRechargeConfigDO> queryWrapper = Wrappers.<CurrencyRechargeConfigDO>lambdaQuery()
				.like(StringUtils.isNotBlank(currencyName), CurrencyRechargeConfigDO::getCurrencyName, currencyName).eq(CurrencyRechargeConfigDO::getDeleted, NumberUtils.INTEGER_ZERO)
				.orderByAsc(CurrencyRechargeConfigDO::getCurrencyAmount);
		return this.page(new Page<>(config.getCurrent(), config.getSize()), queryWrapper);
	}

	/**
	 * 保存
	 *
	 * @param config
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void save(CurrencyRechargeConfigVO config) throws Exception {
		final RLock lock = redissonClient.getLock(DistributedLock.UPSERT_CURRENCY_RECHARGE_CONFIG_KEY);
		if (lock.tryLock(DistributedLock.TIMEOUT_TEN_SEC, TimeUnit.SECONDS)) {
			try {
				final Date now = new Date();
				final Long userId = Long.valueOf(SecurityUtils.getUser().getId());

				final LambdaQueryWrapper<CurrencyRechargeConfigDO> existsWrapper = Wrappers.<CurrencyRechargeConfigDO>lambdaQuery().eq(CurrencyRechargeConfigDO::getCurrencyAmount, config.getCurrencyAmount()).eq(CurrencyRechargeConfigDO::getDeleted, NumberUtils.INTEGER_ZERO);
				if (this.count(existsWrapper) > 0) {
					throw new IllegalArgumentException(String.format("商品金额 %s 在数据库中已存在", config.getCurrencyAmount()));
				}

				final CurrencyRechargeConfigDO insertBean = new CurrencyRechargeConfigDO()
						.setCurrencyName(config.getCurrencyName())
						.setCurrencyAmount(config.getCurrencyAmount())
						.setRechargeAmount(config.getRechargeAmount())
						.setMarked(config.getMarked())
						.setMarkValue(1 == config.getMarked() ? config.getMarkValue() : null)
						.setDeleted(NumberUtils.INTEGER_ZERO)
						.setCreateId(userId)
						.setCreateTime(now)
						.setUpdateId(userId)
						.setUpdateTime(now);
				this.save(insertBean);
			} finally {
				lock.unlock();
			}
		}
	}

	/**
	 * 修改
	 *
	 * @param config
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void edit(CurrencyRechargeConfigVO config) throws Exception {
		final RLock lock = redissonClient.getLock(DistributedLock.UPSERT_CURRENCY_RECHARGE_CONFIG_KEY);
		if (lock.tryLock(DistributedLock.TIMEOUT_TEN_SEC, TimeUnit.SECONDS)) {
			try {
				final Date now = new Date();
				final Long userId = Long.valueOf(SecurityUtils.getUser().getId());

				final LambdaQueryWrapper<CurrencyRechargeConfigDO> existsWrapper = Wrappers.<CurrencyRechargeConfigDO>lambdaQuery()
						.ne(CurrencyRechargeConfigDO::getId, config.getId()).eq(CurrencyRechargeConfigDO::getCurrencyAmount, config.getCurrencyAmount()).eq(CurrencyRechargeConfigDO::getDeleted, NumberUtils.INTEGER_ZERO);
				if (this.count(existsWrapper) > 0) {
					throw new IllegalArgumentException(String.format("游豆数量 %s 在数据库中已存在", config.getCurrencyAmount()));
				}

				final String currencyName = config.getCurrencyName();
				final BigDecimal currencyAmount = config.getCurrencyAmount();
				final BigDecimal rechargeAmount = config.getRechargeAmount();
				final Integer marked = config.getMarked();
				final String markValue = config.getMarkValue();
				final LambdaUpdateWrapper<CurrencyRechargeConfigDO> updateWrapper = Wrappers.<CurrencyRechargeConfigDO>lambdaUpdate()
						.set(StringUtils.isNotBlank(currencyName), CurrencyRechargeConfigDO::getCurrencyName, currencyName)
						.set(Objects.nonNull(currencyAmount), CurrencyRechargeConfigDO::getCurrencyAmount, currencyAmount)
						.set(Objects.nonNull(rechargeAmount), CurrencyRechargeConfigDO::getRechargeAmount, rechargeAmount)
						.set(Objects.nonNull(marked), CurrencyRechargeConfigDO::getMarked, marked)
						.set(CurrencyRechargeConfigDO::getMarkValue, 1 == marked ? markValue : null)
						.set(CurrencyRechargeConfigDO::getUpdateId, userId)
						.set(CurrencyRechargeConfigDO::getUpdateTime, now)
						.eq(CurrencyRechargeConfigDO::getId, config.getId())
						.eq(CurrencyRechargeConfigDO::getDeleted, NumberUtils.INTEGER_ZERO);
				this.update(updateWrapper);
			} finally {
				lock.unlock();
			}
		}
	}

	/**
	 * 删除
	 *
	 * @param id
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void remove(Long id) throws Exception {
		final RLock lock = redissonClient.getLock(DistributedLock.UPSERT_CURRENCY_RECHARGE_CONFIG_KEY);
		if (lock.tryLock(DistributedLock.TIMEOUT_TEN_SEC, TimeUnit.SECONDS)) {
			try {
				final Date now = new Date();
				final Long userId = Long.valueOf(SecurityUtils.getUser().getId());
				final CurrencyRechargeConfigDO insertBean = new CurrencyRechargeConfigDO().setId(id).setDeleted(NumberUtils.INTEGER_ONE).setUpdateId(userId).setUpdateTime(now);
				this.updateById(insertBean);
			} finally {
				lock.unlock();
			}
		}
	}

}




